#!/bin/bash

#
# renphoto -- by Dario Berzano <dario.berzano@gmail.com>
#
# Part of the lfscripts suite -- http://lfscripts.googecode.com/
#
# A tool to nicely rename photos that uses renrot. No rotation is performed,
# and filenames are converted into lowercase if needed. If photos contain an
# associated audio comment in wav, as in many cameras, the wav file is renamed
# accordingly. Please note that it requires libprogressbar and renphoto to be
# installed
#

#
# External libraries
#

# Auto find executable path, following links if needed
export EXEC
export LIBPATH

function SetPaths() {
  local LINK=`readlink "$0"`
  if [ "$LINK" == "" ]; then
    # No symlink
    EXEC="$0"
  elif [ "${LINK:0:1}" == "/" ]; then
    # Absolute symlink
    EXEC="$LINK"
  else
    # Relative symlink
    EXEC=`dirname "$0"`/"$LINK"
  fi
  LIBPATH=`dirname "$EXEC"`
}

# Sets paths
SetPaths

# Loads libraries
source "$LIBPATH/libprogressbar"

#
# Global variables
#

# General purpose
export DRYRUN=0
export VERBOSE=0

#
# Functions
#

# Converts filenames to lower case
function FilesToLower() {

  local SRC
  local DST
  local CNT=0

  ProgressStart "Renaming to lowercase..."
  for SRC in *.{JPG,jpg,JPEG,jpeg,AVI,avi,WAV,wav}
  do
    if [ -e "$SRC" ]; then
      DST=$(echo "$SRC" | tr "[:upper:]" "[:lower:]")
      if [ "$SRC" != "$DST" ]; then
        ProgressStep
        Move "$SRC" "$DST"
        let CNT++
      fi
    fi
  done
  ProgressStop "$CNT file(s) renamed"

}

# The core of the program
function RenPhoto() {

  local SRC
  local DST
  local AUSRC
  local AUDST
  local AUDIO=0
  local CNT=0
  local AUCNT=0
  local OUT=`mktemp /tmp/renphoto.XXXXX`

  if [ "$1" == "--audio" ]; then
    AUDIO=1
  fi

  ProgressStart "Getting rename patterns..."
  renrot --no-use-color --no-rotate --no-mtime --no-tags --dry-run \
    *.{jpg,jpeg} > $OUT 2>&1
  if [ $VERBOSE == 1 ]; then
    cat $OUT
  fi
  ProgressStop

  if [ $AUDIO == 1 ]; then
    ProgressStart "Renaming photos and audio files..."
  else
    ProgressStart "Renaming photos..."
  fi

  while read R
  do
    SRC=$(echo "$R" | perl -ne '/^Renamed: (.+) -> (.+)$/; print "$1\n"')
    DST=$(echo "$R" | perl -ne '/^Renamed: (.+) -> (.+)$/; print "$2\n"')
    if [ "$SRC" == "" ] || [ "$DST" == "" ]; then
      continue
    fi

    Move "$SRC" "$DST"
    ProgressStep
    let CNT++

    # Rename associated audio files
    # Use: ${SRC%.*} to get the filename, ${SRC##*.} for the ext (tested!)
    if [ $AUDIO == 1 ]; then
      AUSRC="${SRC%.*}.wav"
      AUDST="${DST%.*}.wav"
      if [ -e "$AUSRC" ]; then
        Move "$AUSRC" "$AUDST"
        let AUCNT++
      fi
    fi
  done < $OUT

  if [ $AUDIO == 1 ]; then
    ProgressStop "$CNT photo(s), $AUCNT audio file(s) renamed"
  else
    ProgressStop "$CNT photo(s) renamed"
  fi

  rm $OUT

}

# Moves files (verbosely or not, and respects dry-run)
function Move() {
  if [ $DRYRUN == 1 ]; then
    if [ $VERBOSE == 1 ]; then
      echo "I would have moved \"$1\" to \"$2\""
    fi
  else
    if [ $VERBOSE == 1 ]; then
      echo "Moving \"$1\" to \"$2\""
    fi
    mv "$1" "$2"
  fi
}

# Prints the number of JPEG files found in the current directory
function CountJpegs() {
  local CNT=$(ls -1 *.{JPG,jpg,JPEG,jpeg} 2> /dev/null | wc -l)
  echo $CNT
}

# Main function
function Main() {

  # Check if renrot is available
  which renrot > /dev/null 2>&1
  if [ $? != 0 ]; then
    echo "renrot not available, aborting"
    exit 10
  fi

  local BEF
  local AFT=0
  local AUDIO="--audio"
  local ERR=0

  while [ $# -gt 0 ]; do
    case "$1" in
      "--dry-run"|"-n") DRYRUN=1 ;;
      "--verbose"|"-v") VERBOSE=1 ;;
      "--no-audio") AUDIO="" ;;
      *)
        echo "Unknown parameter: $1"
        ERR=1
      ;;
    esac
    shift
  done

  if [ $ERR == 1 ]; then
    echo "Nothing done"
    return
  fi

  BEF=$(CountJpegs)

  FilesToLower
  RenPhoto $AUDIO

  AFT=$(CountJpegs)

  if [ $BEF != $AFT ]; then
    echo -n "WARNING: # of jpegs at beginning ($BEF) does not match # of jpegs "
    echo    "at the end ($AFT)"
  else
    echo "There are $AFT jpegs in this folder"
  fi

}

#
# Entry point
#

Main "$@"
